﻿// Inner Fire 游戏引擎库
// ResourceManager - 资源管理器
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 所属层级：框架层(5)
// 用于游戏中管理资源载入的项目。贴图、模型的载入都靠这个资源管理器统一管理。
// 总之关于内存的一切，都应该集中到这个管理器内部进行管理。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-04-21

#pragma once

#include <dx/graphics/dx_draw_desc.h>
#include <game/resource/material.h>
#include <game/resource/model.h>
#include <game/resource/texture.h>
#include <index_allocator.h>
#include <sprite_pack.h>

namespace ifire::dx {
class DxGraphics;
}

namespace ifire::game {
class Assets;
class GameManager;

struct ResourceLoader {
  Resource* resource;
};

struct TextureLoader {
  Texture* texture;
};

class ResourceManager {
public:
  ResourceManager(GameManager* game_manager);
  ResourceManager(const ResourceManager& lhs) = delete;
  ResourceManager& operator=(const ResourceManager& lhs) = delete;
  ~ResourceManager() = default;

  // 使图形系统准备好载入相关信息
  void ReadyCommand();
  // 提交图形系统所进行的改动
  void CommitCommand();

  // 使一个模型的所有相关联Assets启用
  void LoadModel(Model* model);

  // 载入一个Material
  void LoadMaterial(Material* material);
  void LoadMaterial(ikit::sstr material_name);

  // 载入贴图
  void LoadTexture(Texture* texture);
  void LoadTexture(ikit::sstr texture_name);
  // 载入SpritePack的贴图
  void LoadTexture(ikit::SpritePack* sprite_pack);

  // 配置系统资源
  void SetupSystemResource();

  // 查找一个Texture的索引，如果不存在，返回-1
  int FindTextureIndex(ikit::sstr name);
  // 查找一个Texture并返回指针，如果不存在，返回nullptr
  dx::DxTexture* FindTexture(ikit::sstr name);

  // 创建一个空RenderItem以备使用
  dx::RenderItem* CreateRenderItem(
      dx::RenderLayer layer, bool is_skin_mesh = false);

  // 创建一个Animator
  dx::SkinAnimator* CreateAnimator();

  // 处理水体动画
  void AnimateWaterMaterials();

  // 创建一个Material
  dx::Material* CreateMaterial(const dx::MaterialDesc& desc);
  // 得到一个Material
  dx::Material* FindMaterial(ikit::sstr name);
  // 得到一个Material，按照索引
  dx::Material* GetMaterial(int index);

  void SetToLayer(dx::RenderLayer layer, dx::RenderItem* item);

private:
  GameManager* gm_;
  dx::DxGraphics* dx_;
  Assets* assets_;

  // 用于设置Dx的绘制项目
  dx::DxDrawDesc draw_desc_;

  // 用于保存当前RenderItem的序号
  ikit::index_allocator render_item_index_;
  ikit::index_allocator skinned_item_index_;
  ikit::index_allocator texture_index_;
  ikit::index_allocator material_index_;
  ikit::index_allocator mesh_index_;
  ikit::index_allocator animator_index_;

  int empty_normal_;
  int ui_sprite_index_;
  dx::Material* font_material_;
  dx::Material* water_material_;

  // 纹理贴图
  eastl::vector<dx::TexturePtr> textures_;
  // 材质
  eastl::vector<dx::MaterialPtr> materials_;
  // 游戏对象（GameObject）的总队列
  eastl::vector<dx::RenderItemPtr> items_;
  // 分层的渲染对象
  eastl::vector<dx::RenderItem*> render_layer_[(int)dx::RenderLayer::Count];
  // 用于蒙皮动画
  eastl::vector<dx::SkinAnimatorPtr> animators_;
};

} // namespace ifire::game